home *** CD-ROM | disk | FTP | other *** search
- /* File "mactcp.cpp", Light Sockets - Copyright (C) Matt Slot, 1996 */
- /* MacTCP implementation for "Light Sockets" network abstraction library. */
-
- #include <A4Stuff.h>
- #include <AddressXlation.h>
- #include <LowMem.h>
- #include <MacTCP.h>
- #include <string.h>
-
- #include "stddebug.h"
- #include "stdmacro.h"
- #include "stdtypes.h"
-
- #include "my mactcp.h"
- #include "patches.h"
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* Global/Static Data */
-
- UInt32 MacTCPStack::loadCount = 0;
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
-
- MacTCPStack::MacTCPStack(SocketRef socket) : NetworkStack(socket) {
- refnum = 0;
- stream = 0;
- disposing = false;
- readUPP = 0;
- bfrRtnUPP = 0;
- sendDoneUPP = 0;
- freeQ.qHead = freeQ.qTail = 0;
- busyQ.qHead = busyQ.qTail = 0;
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
-
- MacTCPStack::~MacTCPStack() {
- DoDispose();
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- #pragma mark -
-
- SocketResult MacTCPStack::DoLoad() {
- SocketResult error = eSocketNoError;
-
- /* Implement socket callback chain */
- qThrowIfError(NetworkStack::DoLoad(), 0);
-
- if (! loadCount) {
- /* Load the "first" network stack */
-
- /* Open MacTCP only if it hasn't been loaded before */
- if (! refnum)
- qThrowIfError(OpenDriver("\p.ipp", &refnum),
- "Error opening MacTCP");
- }
- loadCount++;
-
- /* CATCH */
- qCatch();
- return(error);
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
-
- SocketResult MacTCPStack::DoUnload() {
- SocketResult error = eSocketNoError;
-
- /* Parameter validation */
- qAssertIfFalse(refnum, eSocketErrNotLoaded, kSocketErrNotLoadedStr);
-
- loadCount--;
- if (! loadCount) {
- /* Unload the "last" network stack */
-
- /* Normally we would close the network stack, but you don't do that
- for MacTCP. So just sit tight and let the call complete. */
-
- }
-
- /* Implement socket callback chain */
- qThrowIfError(NetworkStack::DoUnload(), 0);
-
- /* CATCH */
- qCatch();
- return(error);
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- #pragma mark -
-
- SocketResult MacTCPStack::DoCreate() {
- SocketResult error = eSocketNoError;
-
- /* Parameter validation */
- qAssertIfFalse(refnum, eSocketErrNotLoaded, kSocketErrNotLoadedStr);
-
- /* Implement socket callback chain */
- qThrowIfError(NetworkStack::DoCreate(), 0);
-
- #if GENERATINGCFM || __A5__
- homeA5 = (UInt32) LMGetCurrentA5();
- #else
- homeA4 = GetCurrentA4();
- #endif
-
- InstallE2STask((E2STaskProc) E2SCleanup, this);
-
- if (qIsSocketTypeUDP(socket->GetSocketType())) {
- UInt32 i;
-
- for(i=0; i<kMacTCPNumParamBlocks; i++)
- Enqueue((QElemPtr) dataBuffs+i, &freeQ);
-
- /* UDPCreate occurs in DoBind() */
- }
- else if (qIsSocketTypeRawIP(socket->GetSocketType())) {
- qThrowErr(eSocketErrNoSupport, kSocketErrNoSupportStr);
- }
- else if (qIsSocketTypeTCP(socket->GetSocketType())) {
- qThrowErr(eSocketErrNoSupport, kSocketErrNoSupportStr);
- }
- // else qThrowErr(eSocketErrBadParam, kSocketErrBadParamStr);
-
-
- /* CATCH */
- qCatch();
- return(error);
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
-
- SocketResult MacTCPStack::DoTickle() {
- SocketResult error = eSocketNoError;
-
- /* Implement socket callback chain */
- qThrowIfError(NetworkStack::DoTickle(), 0);
-
-
- /* CATCH */
- qCatch();
- return(error);
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
-
- SocketResult MacTCPStack::DoDispose() {
- SocketResult error = eSocketNoError;
-
- /* Parameter validation */
- qAssertIfFalse(refnum, eSocketErrNotLoaded, kSocketErrNotLoadedStr);
-
- disposing = true;
- RemoveE2STask((E2STaskProc) E2SCleanup, this);
-
- if (socket) {
- /* In MacTCP, UDP/TCP release acts as an Unbind */
- if (qIsSocketTypeUDP(socket->GetSocketType())) {
- if (stream) {
- UDPiopb udppb;
-
- /* Due to the design of MacTCP, there is no way to cancel an
- outstanding UDPWrite or to release until they have completed.
- This is where we sit and spin until that happens. */
- while(busyQ.qHead)
- socket->Tickle();
-
- udppb.ioCompletion = 0;
- udppb.ioResult = 0;
- udppb.ioCRefNum = refnum;
- udppb.csCode = UDPRelease;
- udppb.udpStream = stream;
- udppb.csParam.create.rcvBuff = 0;
- udppb.csParam.create.rcvBuffLen = 0;
- udppb.csParam.create.userDataPtr = (Ptr) this;
- qTraceIfError(PBControlSync((ParmBlkPtr) &udppb),
- "Unable to Release UDP Stream");
-
- stream = 0;
- }
-
- if (readUPP) {
- DisposeRoutineDescriptor(readUPP);
- readUPP = 0;
- }
- if (bfrRtnUPP) {
- DisposeRoutineDescriptor(bfrRtnUPP);
- bfrRtnUPP = 0;
- }
- if (sendDoneUPP) {
- DisposeRoutineDescriptor(sendDoneUPP);
- sendDoneUPP = 0;
- }
- }
- else if (qIsSocketTypeRawIP(socket->GetSocketType())) {
- qThrowErr(eSocketErrNoSupport, kSocketErrNoSupportStr);
- }
- else if (qIsSocketTypeTCP(socket->GetSocketType())) {
- qThrowErr(eSocketErrNoSupport, kSocketErrNoSupportStr);
- }
- else qThrowErr(eSocketErrBadParam, kSocketErrBadParamStr);
- }
-
- /* Implement socket callback chain */
- qThrowIfError(NetworkStack::DoDispose(), 0);
-
- /* CATCH */
- qCatch();
- return(error);
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- #pragma mark -
-
- SocketResult MacTCPStack::DoBind(SocketAddressPtr reqAddress,
- SocketAddressPtr retAddress) {
- SocketResult error = eSocketNoError;
- UInt16 savePort = 0;
-
- /* Parameter validation */
- qAssertIfFalse(refnum, eSocketErrNotLoaded, kSocketErrNotLoadedStr);
- qAssertIfTrue(stream, eSocketErrWasBound, kSocketErrWasBoundStr);
-
- /* Implement socket callback chain */
- qThrowIfError(NetworkStack::DoBind(reqAddress, retAddress), 0);
-
-
- /* In MacTCP, UDP/TCP Create actually do the Bind */
- if (qIsSocketTypeUDP(socket->GetSocketType())) {
- UDPiopb udppb;
-
- qThrowIfNull(readUPP = NewUDPIOCompletionProc(UDPAsyncRead),
- eSocketErrOutOfMem, kSocketErrOutOfMemStr);
- qThrowIfNull(bfrRtnUPP = NewUDPIOCompletionProc(UDPAsyncBfrRtn),
- eSocketErrOutOfMem, kSocketErrOutOfMemStr);
- qThrowIfNull(sendDoneUPP = NewUDPIOCompletionProc(UDPSendComplete),
- eSocketErrOutOfMem, kSocketErrOutOfMemStr);
-
- udppb.ioCompletion = 0;
- udppb.ioResult = 0;
- udppb.ioCRefNum = refnum;
- udppb.csCode = UDPCreate;
- udppb.udpStream = 0;
- udppb.csParam.create.rcvBuff = (Ptr) buffer;
- udppb.csParam.create.rcvBuffLen = sizeof(buffer);
- udppb.csParam.create.notifyProc = 0;
- udppb.csParam.create.localPort =
- (reqAddress) ? reqAddress->buffer.tcpip.port : 0;
- udppb.csParam.create.userDataPtr = (Ptr) this;
- qThrowIfError(PBControlSync((ParmBlkPtr) &udppb),
- "Unable to Create UDP Stream");
-
- stream = udppb.udpStream;
- savePort = udppb.csParam.create.localPort;
- }
- else if (qIsSocketTypeRawIP(socket->GetSocketType())) {
- qThrowErr(eSocketErrNoSupport, kSocketErrNoSupportStr);
- }
- else if (qIsSocketTypeTCP(socket->GetSocketType())) {
- qThrowErr(eSocketErrNoSupport, kSocketErrNoSupportStr);
- }
- else qThrowErr(eSocketErrBadParam, kSocketErrBadParamStr);
-
- if (retAddress) {
- GetAddrParamBlock addrpb;
-
- addrpb.ioCompletion = 0;
- addrpb.ioResult = 0;
- addrpb.ioCRefNum = refnum;
- addrpb.csCode = ipctlGetAddr;
- addrpb.ourAddress = 0;
- addrpb.ourNetMask = 0;
- qThrowIfError(PBControlSync((ParmBlkPtr) &addrpb),
- "Unable to get Local IP Address");
-
- retAddress->type = socket->GetSocketType();
- retAddress->length = sizeof(retAddress->buffer.tcpip);
- retAddress->buffer.tcpip.type = AF_INET;
- retAddress->buffer.tcpip.port = savePort;
- retAddress->buffer.tcpip.host = addrpb.ourAddress;
- memset(retAddress->buffer.tcpip.data, 0,
- sizeof(retAddress->buffer.tcpip.data));
- }
-
- /* Start any outstanding reads now that the return address is set */
- if (qIsSocketTypeUDP(socket->GetSocketType())) {
- readPB.ioResult = 0;
- readPB.csParam.receive.userDataPtr = (Ptr) this;
- UDPAsyncRead(&readPB);
- }
- else if (qIsSocketTypeRawIP(socket->GetSocketType())) {
- qThrowErr(eSocketErrNoSupport, kSocketErrNoSupportStr);
- }
- else if (qIsSocketTypeTCP(socket->GetSocketType())) {
- qThrowErr(eSocketErrNoSupport, kSocketErrNoSupportStr);
- }
- else qThrowErr(eSocketErrBadParam, kSocketErrBadParamStr);
-
-
- /* CATCH */
- qCatch();
- return(error);
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
-
- SocketResult MacTCPStack::DoUnbind(void) {
- SocketResult error = eSocketNoError;
-
- /* Parameter validation */
- qAssertIfFalse(refnum, eSocketErrNotLoaded, kSocketErrNotLoadedStr);
-
- if (qIsSocketTypeUDP(socket->GetSocketType())) {
- /* UDPRelease occurs in DoDispose(), which can sit and Spin() */
- }
- else if (qIsSocketTypeRawIP(socket->GetSocketType())) {
- qThrowErr(eSocketErrNoSupport, kSocketErrNoSupportStr);
- }
- else if (qIsSocketTypeTCP(socket->GetSocketType())) {
- qThrowErr(eSocketErrNoSupport, kSocketErrNoSupportStr);
- }
- else qThrowErr(eSocketErrBadParam, kSocketErrBadParamStr);
-
- /* Implement socket callback chain */
- qThrowIfError(NetworkStack::DoUnbind(), 0);
-
-
- /* CATCH */
- qCatch();
- return(error);
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- #pragma mark -
-
- SocketResult MacTCPStack::DoAddressResolve(Char8 *textAddress,
- SocketAddressPtr socketAddress) {
- SocketResult error = eSocketNoError;
- Bool8 opened = false;
- Bool8 completed = false;
- hostInfo hInfo;
- #if !GENERATINGCFM
- ResultUPP resultUPP = (ResultUPP) DNRComplete;
- #else
- RoutineDescriptor xRD = BUILD_ROUTINE_DESCRIPTOR(uppResultProcInfo, DNRComplete);
- ResultUPP resultUPP = (ResultUPP) &xRD;
-
- MakeDataExecutable(&xRD, sizeof(xRD));
- #endif
-
- /* Parameter validation */
- qAssertIfFalse(refnum, eSocketErrNotLoaded, kSocketErrNotLoadedStr);
- qAssertIfNull(socketAddress, eSocketErrBadParam, kSocketErrBadParamStr);
- qAssertIfNull(textAddress, eSocketErrBadParam, kSocketErrBadParamStr);
-
- /* Perform the task */
- qThrowIfError(OpenResolver(0), "Error opening DNR");
- opened = true;
-
- error = StrToAddr(textAddress, &hInfo, resultUPP, (Ptr) &completed);
- if (error == cacheFault) {
- error = eSocketNoError;
- qTraceIfError(DoTickle(), 0);
- while(! completed) DoTickle();
- qThrowIfError(hInfo.rtnCode, "Error resolving hostname");
- }
- else qThrowIfError(error, "Error resolving hostname");
-
- socketAddress->type = eSocketTypeUDP; /* For a guess */
- socketAddress->length = sizeof(socketAddress->buffer.tcpip);
- socketAddress->buffer.tcpip.type = AF_INET;
- socketAddress->buffer.tcpip.port = 0;
- socketAddress->buffer.tcpip.host = hInfo.addr[0];
- memset(socketAddress->buffer.tcpip.data, 0,
- sizeof(socketAddress->buffer.tcpip.data));
-
- /* CATCH */
- qCatch();
-
- if (opened)
- qTraceIfError(CloseResolver(), "Error closing DNR");
-
- return(error);
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
-
- SocketResult MacTCPStack::DoAddressLookup(SocketAddressPtr socketAddress,
- Char8 *textAddress) {
- SocketResult error = eSocketNoError;
- Bool8 opened = false;
- Bool8 completed = false;
- hostInfo hInfo;
- #if !GENERATINGCFM
- ResultUPP resultUPP = (ResultUPP) DNRComplete;
- #else
- RoutineDescriptor xRD = BUILD_ROUTINE_DESCRIPTOR(uppResultProcInfo, DNRComplete);
- ResultUPP resultUPP = (ResultUPP) &xRD;
-
- MakeDataExecutable(&xRD, sizeof(xRD));
- #endif
-
- /* Parameter validation */
- qAssertIfFalse(refnum, eSocketErrNotLoaded, kSocketErrNotLoadedStr);
- qAssertIfNull(socketAddress, eSocketErrBadParam, kSocketErrBadParamStr);
- qAssertIfNull(textAddress, eSocketErrBadParam, kSocketErrBadParamStr);
-
- /* Perform the task */
- qThrowIfError(OpenResolver(0), "Error opening DNR");
- opened = true;
-
- error = AddrToName(socketAddress->buffer.tcpip.host, &hInfo,
- resultUPP, (Ptr) &completed);
- if (error == cacheFault) {
- error = eSocketNoError;
- qTraceIfError(DoTickle(), 0);
- while(! completed) DoTickle();
- qThrowIfError(hInfo.rtnCode, "Error looking up hostname");
- strcpy(textAddress, hInfo.cname);
-
- /* MacTCP returns hostnames with a trailing '.' -- clip it */
- if (*textAddress && textAddress[strlen(textAddress)-1] == '.')
- textAddress[strlen(textAddress)-1] = 0;
- }
- else qThrowIfError(error, "Error looking up hostname");
-
-
- /* CATCH */
- qCatch();
-
- if (error && textAddress) *textAddress = 0;
- if (opened) qTraceIfError(CloseResolver(), "Error closing DNR");
- return(error);
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- #pragma mark -
-
- SocketResult MacTCPStack::DoDatagramWrite(Byte8 *dataPtr, UInt32 dataLen,
- SocketAddressPtr address) {
- SocketResult error = eSocketNoError;
- MacTCPDataPtr writeData;
-
- /* Parameter validation */
- qAssertIfFalse(refnum, eSocketErrNotLoaded, kSocketErrNotLoadedStr);
- qThrowIfTrue(disposing, eSocketErrInternal,
- "Can't Send on a Closing socket");
-
- /* Pop off a new container */
- qThrowIfNull(writeData = (MacTCPDataPtr) freeQ.qHead, eSocketErrFlooded,
- "Too many outstanding writes");
- qThrowIfError(Dequeue((QElem *) writeData, &freeQ),
- "Unable to extract write buffer");
-
- BlockMoveData(dataPtr, writeData->dataBuff, dataLen);
- writeData->wds[0].length = writeData->dataLen = dataLen;
- writeData->wds[0].ptr = (Ptr) writeData->dataBuff;
- writeData->wds[1].length = 0;
-
- /* Make the UDP Write */
- writeData->pb.udppb.ioCompletion = sendDoneUPP;
- writeData->pb.udppb.ioCRefNum = refnum;
- writeData->pb.udppb.csCode = UDPWrite;
- writeData->pb.udppb.udpStream = stream;
- writeData->pb.udppb.csParam.send.reserved = 0;
- writeData->pb.udppb.csParam.send.remoteHost = address->buffer.tcpip.host;
- writeData->pb.udppb.csParam.send.remotePort = address->buffer.tcpip.port;
- writeData->pb.udppb.csParam.send.wdsPtr = (Ptr) writeData->wds;
- writeData->pb.udppb.csParam.send.checkSum = false;
- writeData->pb.udppb.csParam.send.filler = 0;
- writeData->pb.udppb.csParam.send.sendLength = writeData->dataLen;
- writeData->pb.udppb.csParam.send.userDataPtr = (Ptr) this;
- writeData->pb.udppb.csParam.send.localPort = 0;
-
- qEnqueue((QElem *) writeData, &busyQ);
- if (error = PBControlAsync((ParmBlkPtr) &writeData->pb.udppb)) {
- #if (_DEBUGSAFE)
- qThrowIfError(error, "Unable to Send on UDP Stream");
- qThrowIfError(Dequeue((QElem *) writeData, &busyQ),
- "Unable to restore write buffer");
- #else
- Dequeue((QElem *) writeData, &busyQ);
- #endif
- qEnqueue((QElem *) writeData, &freeQ);
- }
-
- /* Implement socket callback chain */
- qThrowIfError(NetworkStack::DoDatagramWrite(dataPtr, dataLen, address), 0);
-
-
- /* CATCH */
- qCatch();
- return(error);
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- #pragma mark -
-
- SocketResult MacTCPStack::DoStreamServer(UInt32 sessions) {
- return(eSocketErrNoSupport); /* Function not supported yet */
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
-
- SocketResult MacTCPStack::DoStreamClient(SocketAddressPtr address) {
- return(eSocketErrNoSupport); /* Function not supported yet */
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
-
- SocketResult MacTCPStack::DoStreamWrite(Byte8 *dataPtr, UInt32 dataLen) {
- return(eSocketErrNoSupport); /* Function not supported yet */
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
-
- SocketResult MacTCPStack::DoStreamClose(Bool8 orderly) {
- return(eSocketErrNoSupport); /* Function not supported yet */
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- #pragma mark -
-
- pascal void MacTCPStack::DNRComplete(hostInfo *hInfo, Bool8 *doneFlag) {
- *doneFlag = true;
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
-
- void MacTCPStack::UDPAsyncRead(UDPiopb *udppb) {
- MacTCPStackRef stack = (MacTCPStackRef) udppb->csParam.receive.userDataPtr;
- #if GENERATINGCFM || __A5__
- UInt32 saveA5 = SetA5(stack->homeA5);
- #else
- UInt32 saveA4 = GetCurrentA4(stack->homeA4);
- #endif
- SocketResult error = eSocketNoError;
-
- /* Parameter validation */
- #if (_DEBUGSAFE)
- qAssertIfNull(udppb, eSocketErrInternal, kSocketErrInternalStr);
- qAssertIfNull(stack, eSocketErrInternal, kSocketErrInternalStr);
- #endif
-
- /* Perform UDP Receive */
- if (udppb->ioResult != connectionTerminated) {
- #if (_DEBUGSAFE)
- qThrowIfError(udppb->ioResult, "Error Returning Buffer on UDP Stream");
- #endif
-
- udppb->ioCompletion = stack->bfrRtnUPP;
- udppb->ioResult = 0;
- udppb->ioCRefNum = stack->refnum;
- udppb->csCode = UDPRead;
- udppb->udpStream = stack->stream;
- udppb->csParam.receive.timeOut = 0;
- udppb->csParam.receive.remoteHost = 0;
- udppb->csParam.receive.remotePort = 0;
- udppb->csParam.receive.rcvBuff = 0;
- udppb->csParam.receive.rcvBuffLen = 0;
- udppb->csParam.receive.secondTimeStamp = 0;
- udppb->csParam.receive.userDataPtr = (Ptr) stack;
- #if (_DEBUGSAFE)
- qThrowIfError(PBControlAsync((ParmBlkPtr) udppb),
- "Unable to Receive on UDP Stream");
- #else
- error = PBControlAsync((ParmBlkPtr) &udppb);
- #endif
- }
-
-
- /* CATCH */
- qCatch();
-
- #if GENERATINGCFM || __A5__
- SetA5(saveA5);
- #else
- SetA4(saveA4);
- #endif
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
-
- void MacTCPStack::UDPAsyncBfrRtn(UDPiopb *udppb) {
- MacTCPStackRef stack = (MacTCPStackRef) udppb->csParam.receive.userDataPtr;
- #if GENERATINGCFM || __A5__
- UInt32 saveA5 = SetA5(stack->homeA5);
- #else
- UInt32 saveA4 = GetCurrentA4(stack->homeA4);
- #endif
- SocketResult error = eSocketNoError;
-
- /* Parameter validation */
- #if (_DEBUGSAFE)
- qAssertIfNull(udppb, eSocketErrInternal, kSocketErrInternalStr);
- qAssertIfNull(stack, eSocketErrInternal, kSocketErrInternalStr);
- #endif
-
- /* Implement socket callback chain */
- if (! udppb->ioResult) {
- SocketAddress address;
-
- address.type = AF_INET;
- address.length = sizeof(address.buffer.tcpip);
- address.buffer.tcpip.type = 2;
- address.buffer.tcpip.port = udppb->csParam.receive.remotePort;
- address.buffer.tcpip.host = udppb->csParam.receive.remoteHost;
- memset(address.buffer.tcpip.data, 0,
- sizeof(address.buffer.tcpip.data));
-
- #if (_DEBUGSAFE)
- qThrowIfError(stack->DatagramRead(udppb->csParam.receive.rcvBuff,
- udppb->csParam.receive.rcvBuffLen, &address), 0);
- #else
- stack->DatagramRead(udppb->csParam.receive.rcvBuff,
- udppb->csParam.receive.rcvBuffLen, &address);
- #endif
- }
-
- /* Perform UDP Buffer Return */
- if (udppb->ioResult != connectionTerminated) {
- #if (_DEBUGSAFE)
- qThrowIfError(udppb->ioResult, "Error Reading from UDP Stream");
- #endif
-
- udppb->ioCompletion = stack->readUPP;
- udppb->ioResult = 0;
- udppb->ioCRefNum = stack->refnum;
- udppb->csCode = UDPBfrReturn;
- udppb->udpStream = stack->stream;
- udppb->csParam.receive.timeOut = 0;
- udppb->csParam.receive.userDataPtr = (Ptr) stack;
- #if (_DEBUGSAFE)
- qThrowIfError(PBControlAsync((ParmBlkPtr) udppb),
- "Unable to Return Buffer on UDP Stream");
- #else
- error = PBControlAsync((ParmBlkPtr) &udppb);
- #endif
- }
-
-
- /* CATCH */
- qCatch();
-
- #if GENERATINGCFM || __A5__
- SetA5(saveA5);
- #else
- SetA4(saveA4);
- #endif
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
-
- void MacTCPStack::UDPSendComplete(UDPiopb *udppb) {
- MacTCPStackRef stack = (MacTCPStackRef) udppb->csParam.send.userDataPtr;
- #if GENERATINGCFM || __A5__
- UInt32 saveA5 = SetA5(stack->homeA5);
- #else
- UInt32 saveA4 = GetCurrentA4(stack->homeA4);
- #endif
- SocketResult error = eSocketNoError;
- MacTCPDataPtr writeData = (MacTCPDataPtr) udppb;
-
- /* Parameter validation */
- #if (_DEBUGSAFE)
- qAssertIfNull(udppb, eSocketErrInternal, kSocketErrInternalStr);
- qAssertIfNull(stack, eSocketErrInternal, kSocketErrInternalStr);
- qTraceIfError(udppb->ioResult, "Error Sending on UDP Stream");
- #endif
-
- /* Return the data container */
- #if (_DEBUGSAFE)
- qThrowIfError(Dequeue((QElem *) writeData, &stack->busyQ),
- "Unable to release write buffer");
- #else
- Dequeue((QElem *) writeData, &stack->busyQ);
- #endif
- qEnqueue((QElem *) writeData, &stack->freeQ);
-
-
- /* CATCH */
- qCatch();
-
- #if GENERATINGCFM || __A5__
- SetA5(saveA5);
- #else
- SetA4(saveA4);
- #endif
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
-
- void MacTCPStack::E2SCleanup(MacTCPStackRef stack) {
- #if GENERATINGCFM || __A5__
- UInt32 saveA5 = SetA5(stack->homeA5);
- #else
- UInt32 saveA4 = GetCurrentA4(stack->homeA4);
- #endif
- SocketResult error = eSocketNoError;
-
- if (stack && stack->stream)
- #if (_DEBUGSAFE)
- qTraceIfError(stack->DoDispose(), 0);
- #else
- error = stack->DoDispose();
- #endif
-
-
- /* CATCH */
- qCatch();
-
- #if GENERATINGCFM || __A5__
- SetA5(saveA5);
- #else
- SetA4(saveA4);
- #endif
- }
-
-